#pragma once
#include <boost/asio.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/beast/core/flat_buffer.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/http/dynamic_body.hpp>
#include <boost/beast/http/message.hpp>
#include <memory>
#include <string>

namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
using tcp = net::ip::tcp;

class HttpConnection : public std::enable_shared_from_this<HttpConnection> {
private:
  friend class LogicSystem;
  tcp::socket _socket;
  beast::flat_buffer _buffer{8192};
  http::request<http::dynamic_body> _request;
  http::response<http::dynamic_body> _response;
  net::steady_timer _deadline;
  std::string _get_url;
  std::map<std::string, std::string> _get_params;

private:
  void checkDeadline();
  void writeResponse();
  void HandleReq();
  unsigned char ToHex(unsigned char);
  unsigned char FromHex(unsigned char);
  std::string UrlEncode(const std::string &);
  std::string UrlDecode(const std::string &);
  void PreParseGetParam();

public:
  HttpConnection(net::io_context &);
  void Start();
  net::ip::tcp::socket &GetSocket();
};